﻿using GBT.Client.Config;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GBT.Client.FileOperation
{
    public class FtpOperation
    {
        FtpClient ftpClient;

        public FtpOperation(string userName, string password)
        {
            string localAddress = Settings.localIP;
            if (localAddress.PingHost())
            {
                //FTP:PORT: 8090 
                ftpClient = new FtpClient(localAddress, Settings.ftpPost, userName, password, Settings.domainName);
                ftpClient.Connect();
            }
            else
            {
                ftpClient = new FtpClient(Settings.URL, Settings.ftpPost, userName, password, Settings.domainName);
                ftpClient.Connect();
            }
        }

#pragma warning disable CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。
        public string GetDirectory(ref List<TreeNode> treeNodes, ref List<ListViewItem> listViewItems, string? path = null, View view = View.LargeIcon)
#pragma warning restore CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。
        {
            FtpListItem[] ftpListItems = null;
            if (string.IsNullOrWhiteSpace(path))
            {
                ftpListItems = ftpClient.GetListing();
            }
            else
            {
                ftpListItems = ftpClient.GetListing(path);
            }
            int directory = 0;
            int file = 0;
            int fileImageIndex = 0;
            ImageEntity imageEntity = new ImageEntity();
            StringBuilder stringBuilder = new StringBuilder();
            lock (ImageInfo.imageEntityList)
            {
                foreach (FtpListItem ftpListItem in ftpListItems)
                {
                    TreeNode treeNode = new TreeNode();

                    switch (ftpListItem.Type)
                    {
                        case FtpFileSystemObjectType.Directory:
                            //目录
                            treeNode.Text = ftpListItem.Name;
                            treeNode.ImageIndex = 0;
                            treeNode.SelectedImageIndex = 1;
                            treeNodes.Add(treeNode);
                            listViewItems.SetListViewItems(ftpListItem, 1, "directory", view);
                            directory++;
                            break;
                        case FtpFileSystemObjectType.File:
                            //文件
                            bool isExtension = ImageInfo.imageEntityList.Where(t => t.imageExtension == ftpListItem.Name.ToExtension().ToLower()).Any();
                            if (!isExtension)
                            {
                                imageEntity = new ImageEntity();
                                imageEntity.imageExtension = ftpListItem.Name.ToExtension().ToLower();
                                imageEntity.image = ftpListItem.Name.ToLower().GetFileIcon(true);
                                imageEntity.imageIndex = ImageInfo.fileImageIndex + 1;
                                ImageInfo.imageEntityList.Add(imageEntity);
                                ImageInfo.fileImageIndex = imageEntity.imageIndex;
                                fileImageIndex = imageEntity.imageIndex;
                            }
                            else
                            {
                                fileImageIndex = ImageInfo.imageEntityList.Where(t => t.imageExtension == ftpListItem.Name.ToExtension().ToLower()).Select(t => t.imageIndex).FirstOrDefault();
                            }
                            listViewItems.SetListViewItems(ftpListItem, fileImageIndex, "file", view);
                            file++;
                            break;
                        case FtpFileSystemObjectType.Link:
                            //链接

                            break;
                    }
                }
            }
            return "Total: " + directory.ToString() + " directorys, " + file.ToString() + " files";
        }

        public bool Download(string localPath, string remotePath, string tag = null)
        {
            bool isSuccess = false;
            switch (tag)
            {
                case "directory":
                    List<FtpResult> ftpResults = ftpClient.DownloadDirectory(localPath, remotePath);
                    foreach (FtpResult ftpResult in ftpResults)
                    {
                        if (ftpResult.IsSuccess)
                        {
                            isSuccess = true;
                        }
                        else
                        {
                            isSuccess = false;
                            break;
                        }
                    }
                    break;
                case "file":
                    FtpStatus ftpStatus = ftpClient.DownloadFile(localPath, remotePath);
                    isSuccess = ftpStatus.IsSuccess();
                    break;
            }
            return isSuccess;
        }

        public FtpStatus DownloadFile(string localPath, string remotePath)
        {
            return ftpClient.DownloadFile(localPath, remotePath);
        }

        public int DownloadFiles(string localDar, IEnumerable<string> remotePaths)
        {
            return ftpClient.DownloadFiles(localDar, remotePaths);
        }

        public List<FtpResult> DownloadDirectory(string localFolder, string remoteFolder)
        {
            return ftpClient.DownloadDirectory(localFolder, remoteFolder);
        }

        public bool Upload(string localPath, string remotePath, string tag = null)
        {
            bool isSuccess = false;
            switch (tag)
            {
                case "directory":
                    List<FtpResult> ftpResults = ftpClient.UploadDirectory(localPath, remotePath);
                    foreach (FtpResult ftpResult in ftpResults)
                    {
                        if (ftpResult.IsSuccess)
                        {
                            isSuccess = true;
                        }
                        else
                        {
                            isSuccess = false;
                            break;
                        }
                    }
                    break;
                case "file":
                    FtpStatus ftpStatus = ftpClient.UploadFile(localPath, remotePath);
                    isSuccess = ftpStatus.IsSuccess();
                    break;
            }
            return isSuccess;
        }

        public FtpStatus UploadFile(string localPath, string remotePath)
        {
            return ftpClient.UploadFile(localPath, remotePath);
        }

        public int UploadFiles(IEnumerable<string> localPaths, string remoteDir) 
        {
            return ftpClient.UploadFiles(localPaths, remoteDir);
        }

        public List<FtpResult> UploadDirectory(string localDir, string remoteDir)
        {
            return ftpClient.UploadDirectory(localDir, remoteDir);
        }

        public void DeleteDerectoryOrFile(string remotePath, string tag)
        {
            switch (tag)
            {
                case "directory":
                    ftpClient.DeleteDirectory(remotePath);
                    break;
                case "file":
                    ftpClient.DeleteFile(remotePath);
                    break;
            }
        }

        public void MoveDirectoryOrFile(string remotePath, string destPath, string tag)
        {
            switch (tag)
            {
                case "directory":
                    ftpClient.MoveDirectory(remotePath, destPath);
                    break;
                case "file":
                    ftpClient.MoveFile(remotePath, destPath);
                    break;
            }
        }

        public bool CreateDirectory(string path)
        {
            return ftpClient.CreateDirectory(path);
        }

        public bool IsDirectoryExists(string remoteDir)
        {
            return ftpClient.DirectoryExists(remoteDir);
        }

        public bool IsFileExists(string remotePath)
        {
            return ftpClient.FileExists(remotePath);
        }

        public void Rename(string remotePath, string dest)
        {
            ftpClient.Rename(remotePath, dest);
        }
    }
}
